"""
智能更新README和统计脚本
- 自动检测新的作业目录
- 更新generate_submissions.py以支持新作业
- 运行统计脚本更新README
"""

from __future__ import annotations

import re
import subprocess
import sys
from pathlib import Path
from datetime import datetime


def detect_assignment_dirs(repo_root: Path) -> list[tuple[int, str, Path]]:
    """
    检测所有作业目录
    返回: [(序号, 目录名, 路径), ...]
    """
    pattern = re.compile(r"^第([一二三四五六七八九十百]+)次作业$")
    chinese_nums = {
        "一": 1, "二": 2, "三": 3, "四": 4, "五": 5,
        "六": 6, "七": 7, "八": 8, "九": 9, "十": 10,
    }
    
    assignments = []
    for item in repo_root.iterdir():
        if item.is_dir():
            match = pattern.match(item.name)
            if match:
                chinese_num = match.group(1)
                # 简单转换（支持一到十）
                num = chinese_nums.get(chinese_num, 0)
                if num > 0:
                    assignments.append((num, item.name, item))
    
    return sorted(assignments, key=lambda x: x[0])


def check_if_script_needs_update(script_path: Path, assignments: list[tuple[int, str, Path]]) -> bool:
    """
    检查generate_submissions.py是否需要更新
    """
    if not script_path.exists():
        return True
    
    content = script_path.read_text(encoding="utf-8")
    
    # 检查每个作业目录是否在脚本中
    for num, dirname, _ in assignments:
        if f'"{dirname}"' not in content:
            return True
    
    return False


def update_generate_script(script_path: Path, assignments: list[tuple[int, str, Path]]) -> None:
    """
    更新generate_submissions.py以支持所有检测到的作业
    """
    # 生成assignments列表代码
    assignments_code_lines = ["    assignments = ["]
    
    for num, dirname, _ in assignments:
        if num == 1:
            # 第一次作业特殊处理（只有文件模式）
            assignments_code_lines.append(f"""        {{
            "dir": "{dirname}",
            "label": "{dirname}",
            "file_patterns": [re.compile(r"^第一次课作业[-_](?P<name>.+)\\.md$", re.IGNORECASE)],
            "dir_patterns": [],
        }},""")
        else:
            # 其他作业支持文件和目录模式
            assignments_code_lines.append(f"""        {{
            "dir": "{dirname}",
            "label": "{dirname}",
            "file_patterns": [re.compile(r"^{dirname}[-_](?P<name>.+)\\.md$", re.IGNORECASE)],
            "dir_patterns": [re.compile(r"^{dirname}[-_](?P<name>.+)$", re.IGNORECASE)],
        }},""")
    
    assignments_code_lines.append("    ]")
    assignments_code = "\n".join(assignments_code_lines)
    
    # 读取原脚本
    content = script_path.read_text(encoding="utf-8")
    
    # 替换assignments定义（从第9行到第34行）
    pattern = re.compile(
        r"(    assignments = \[)[\s\S]*?(\n    \])",
        re.MULTILINE
    )
    
    new_content = pattern.sub(assignments_code, content)
    
    # 更新headers列表
    headers = ["姓名/代号"] + [dirname for _, dirname, _ in assignments]
    headers_code = '    headers = ["' + '", "'.join(headers) + '"]'
    
    # 替换所有headers定义
    new_content = re.sub(
        r'    headers = \["姓名/代号"[^\]]*\]',
        headers_code,
        new_content
    )
    
    # 更新render函数中的字段访问
    # 先生成字段访问代码
    field_vars = []
    field_links = []
    for num, dirname, _ in assignments:
        var_name = f"hw{num}"
        field_vars.append(f'        {var_name} = submission_map[name].get("{dirname}")')
        field_links.append(f"{{link_or_cross({var_name})}}")
    
    fields_code = "\n".join(field_vars)
    links_code = " | ".join(field_links)
    
    # 替换render_markdown函数中的字段处理
    render_pattern = re.compile(
        r"(    for name in names:\n)(        \w+ = submission_map\[name\]\.get\([^\)]+\)\n)*"
        r"(        lines\.append\(\n            f\"\| \{name\} \|[^\n]+\n        \)\n)",
        re.MULTILINE
    )
    
    render_replacement = f"""    for name in names:
{fields_code}
        lines.append(
            f"| {{name}} | {links_code} |"
        )
"""
    
    new_content = render_pattern.sub(render_replacement, new_content)
    
    # 替换render_table_only函数中的字段处理
    table_pattern = re.compile(
        r"(    for name in names:\n)(        \w+ = submission_map\[name\]\.get\([^\)]+\)\n)*"
        r"(        lines\.append\(\n            f\"\| \{name\} \|[^\n]+\n        \)\n)",
        re.MULTILINE
    )
    
    new_content = table_pattern.sub(render_replacement, new_content)
    
    # 写回文件
    script_path.write_text(new_content, encoding="utf-8")
    print(f"✓ 已更新 {script_path.name} 以支持 {len(assignments)} 次作业")


def update_readme_structure(readme_path: Path, assignments: list[tuple[int, str, Path]]) -> bool:
    """
    更新README中的目录结构说明
    返回是否有更新
    """
    if not readme_path.exists():
        return False
    
    content = readme_path.read_text(encoding="utf-8")
    
    # 查找目录结构部分
    structure_pattern = re.compile(
        r"(```text\ncontribute/\n)(.*?)(```)",
        re.DOTALL
    )
    
    match = structure_pattern.search(content)
    if not match:
        return False
    
    # 生成新的目录结构
    structure_lines = []
    for i, (num, dirname, path) in enumerate(assignments):
        prefix = "├─" if i < len(assignments) - 1 else "├─"
        
        # 根据作业次数添加注释
        if num == 1:
            comment = "# 第 1 次作业提交目录"
        elif num == 2:
            comment = "# 第 2 次作业提交目录"
        elif num >= 3:
            # 检查是否有提交要求文件
            req_file = path / f"{dirname}提交要求.md"
            if req_file.exists():
                comment = "# 工程/文档类作业（含提交要求）"
            else:
                comment = f"# 第 {num} 次作业提交目录"
        else:
            comment = f"# 第 {num} 次作业提交目录"
        
        structure_lines.append(f"{prefix} {dirname}/{'': <{20-len(dirname)}} {comment}")
    
    # 添加其他固定目录
    structure_lines.extend([
        "├─ tools/                # 统计脚本与辅助工具（如 generate_submissions.py）",
        "├─ SUBMISSIONS.md        # 作业提交统计（自动生成）",
        "├─ LICENSE               # 许可协议",
        "├─ NOTICE                # Apache-2.0 NOTICE（信息性）",
        "└─ README.md             # 项目说明（本文件）",
    ])
    
    new_structure = "\n".join(structure_lines)
    old_structure = match.group(2).strip()
    
    if new_structure == old_structure:
        return False
    
    # 替换目录结构
    new_content = structure_pattern.sub(
        f"\\1{new_structure}\n\\3",
        content
    )
    
    readme_path.write_text(new_content, encoding="utf-8")
    return True


def main():
    repo_root = Path(__file__).resolve().parents[1]
    
    print("=" * 60)
    print("智能README更新工具")
    print("=" * 60)
    print()
    
    # 1. 检测作业目录
    print("1. 检测作业目录...")
    assignments = detect_assignment_dirs(repo_root)
    
    if not assignments:
        print("   ✗ 未检测到任何作业目录")
        return 1
    
    print(f"   ✓ 检测到 {len(assignments)} 个作业目录:")
    for num, dirname, _ in assignments:
        print(f"     - {dirname}")
    print()
    
    # 2. 检查并更新统计脚本
    print("2. 检查统计脚本...")
    script_path = repo_root / "tools" / "generate_submissions.py"
    
    if check_if_script_needs_update(script_path, assignments):
        print("   → 需要更新统计脚本")
        update_generate_script(script_path, assignments)
    else:
        print("   ✓ 统计脚本已是最新")
    print()
    
    # 3. 更新README目录结构
    print("3. 更新README目录结构...")
    readme_path = repo_root / "README.md"
    
    if update_readme_structure(readme_path, assignments):
        print("   ✓ README目录结构已更新")
    else:
        print("   ✓ README目录结构已是最新")
    print()
    
    # 4. 运行统计脚本
    print("4. 运行统计脚本更新提交统计...")
    try:
        result = subprocess.run(
            [sys.executable, str(script_path)],
            cwd=str(repo_root),
            capture_output=True,
            text=True,
            check=True
        )
        print("   ✓ 提交统计已更新")
    except subprocess.CalledProcessError as e:
        print(f"   ✗ 统计脚本执行失败: {e}")
        if e.stdout:
            print(f"   输出: {e.stdout}")
        if e.stderr:
            print(f"   错误: {e.stderr}")
        return 1
    print()
    
    print("=" * 60)
    print(f"✓ 更新完成! ({datetime.now().strftime('%Y-%m-%d %H:%M:%S')})")
    print("=" * 60)
    
    return 0


if __name__ == "__main__":
    sys.exit(main())

